package com.yunduo.config.shiro;

import com.yunduo.config.shiro.realm.YunDuoAuthRealm;
import com.yunduo.filter.YunDuoFormAuthenticationFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AllSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Shiro 配置类
 */
@Configuration
public class ShiroConfig {
    @Resource
    private YunDuoAuthRealm yunDuoAuthRealm;

    //加密算法
    @Value("${yunduo.shiro.encryAlgorithm}")
    public String encryAlgorithm;

    //加密次数
    @Value("${yunduo.shiro.count}")
    public int encryCount;

    //盐
    @Value("${yunduo.shiro.salt}")
    public String salt;

    //配置SecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(){
      //创建安全管理器
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
      //创建认证策略
        ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
        //配置具体认证策略
        modularRealmAuthenticator.setAuthenticationStrategy(new AllSuccessfulStrategy());
        //配置安全管理器的认证策略
        securityManager.setAuthenticator(modularRealmAuthenticator);
      //创建加密对象
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //设置加密方式
        matcher.setHashAlgorithmName(encryAlgorithm);
        //迭代加密次数
        matcher.setHashIterations(encryCount);
        //加密对象放入认证类中
        yunDuoAuthRealm.setCredentialsMatcher(matcher);
      //认证类放入安全管理器
        securityManager.setRealm(yunDuoAuthRealm);
        //securityManager.setRealms(); 多个认证类
        return securityManager;
    }

    //过滤器
//    @Bean
//    public DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition(){
//        DefaultShiroFilterChainDefinition defintion = new DefaultShiroFilterChainDefinition();
//        //设置公共资源 地址 , 拦截器 anon 匿名拦截器
//        defintion.addPathDefinition("/auth/login","anon");
//        //设置私有资源 authc登录拦截器
//        defintion.addPathDefinition("/**","authc");
////        defintion.addPathDefinition("/**","anon");
//        //设置后台管理页面需要权限
//        defintion.addPathDefinition("/admin","user");
//        return defintion;
//    }

//    //前后端分离配置响应json数据以及token登录
//    @Bean
//    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, ShiroFilterChainDefinition shiroFilterChainDefinition){
//        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//        shiroFilterFactoryBean.setSecurityManager(securityManager);
//        // 设置自定义的Shiro过滤器
//        Map<String, Filter> filters = new LinkedHashMap<>();
//        filters.put("authc", new YunDuoFormAuthenticationFilter());
//        shiroFilterFactoryBean.setFilters(filters);
//        shiroFilterChainDefinition.getFilterChainMap();
//        return shiroFilterFactoryBean;
//    }

    //过滤与拦截
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        //shiroFilter.setLoginUrl("/401");
        //shiroFilter.setUnauthorizedUrl("/401");
        //这是重点   将拦截器添加到shrio配置类中
        Map<String, Filter> filters = shiroFilter.getFilters();
        filters.put("authc", new YunDuoFormAuthenticationFilter());
        shiroFilter.setFilters(filters);
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/auth/login","anon");
        filterMap.put("/**","authc");
        filterMap.put("/admin","user");
        filterMap.put("/PFile/up","anon");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

    //解决aspectJ与Shiro权限冲突问题 导致controller请求404
    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
        //defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); 任意一个为真
        return defaultAdvisorAutoProxyCreator;
    }
}
